package org.stanzmaster.service;

import org.stanzmaster.entity.*;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import javax.ejb.Local;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.ejb.Stateless;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeBodyPart;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.naming.InitialContext;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.rmi.*;
import javax.sql.DataSource;
import java.sql.Timestamp;
import java.util.Calendar;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import org.stanzmaster.entity.User;

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Local(CrudService.class)
public class CrudServiceBean implements CrudService {
   
    @PersistenceContext
    protected EntityManager em;
    
    @SuppressWarnings("unchecked")
    public String login(String nick, String pass) {
    	Query query = em.createQuery("select usName from " + User.class.getName() + " where usNick = '" +  nick  + "' and usPass = '" + pass + "'");
    	return query.getSingleResult().toString();
    }
    
    @SuppressWarnings("unchecked")
	public int insertStanz(Stanz st, String user)
    {
    	this.em.persist(st);
    	this.em.flush();
    	insertHistory(user, st.getStLabel(), "new stanz");
    	return 1;
    }
    
    public Stanz updateStanz(Stanz st, String user)
    {
    	insertHistory(user, st.getStLabel(), "update stanz");
    	return em.merge(st);
    }
    
    public void deleteStanz(int stId, String user)
    {
    	Stanz st = em.find(Stanz.class, stId);
        if (st != null) {
        	insertHistory(user, st.getStLabel(), "delete stanz");
        	em.remove(st);
        } 
    }
    
    @SuppressWarnings("unchecked")
    public List<History> returnAllHistory() {
        Query query = em.createQuery("from " + History.class.getName());
        return query.getResultList();
    }
    
    @SuppressWarnings("unchecked")
    public List<Stanz> returnAllStanz() {
        Query query = em.createQuery("from " + Stanz.class.getName());
        return query.getResultList();
    }   
    
    public int insertHistory(String user, String st_label, String ev)
    {
    	History hs = new History();
    	hs.setHsUsName(user);
    	hs.setHsStLabel(st_label);
    	hs.setHsEvent(ev);
    	Calendar calendar = Calendar.getInstance();
    	java.util.Date now = calendar.getTime();
    	Timestamp ts = new java.sql.Timestamp(now.getTime());
    	hs.setHsDate(ts);
    	this.em.persist(hs);
    	this.em.flush();
    	return 1;
    }
    
    public int insertContact(Contact ct)
    {
    	this.em.persist(ct);
    	this.em.flush();
    	return 1;
    }
    
	public Contact updateContact(Contact ct)
	{
		return em.merge(ct);
	}
	
	public void deleteContact(int ctId)
	{
		Contact ct = em.find(Contact.class, ctId);
        if (ct != null) {
        	em.remove(ct);
        } 
	}
	
	@SuppressWarnings("unchecked")
	public List<Contact> returnAllContact()
	{
		Query query = em.createQuery("from " + Contact.class.getName());
        return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<String> returnAllCustomer()
	{
		Query query = em.createQuery("select DISTINCT stCustomer from " + Stanz.class.getName());
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<String> returnAllProduct()
	{
		Query query = em.createQuery("select DISTINCT stProduct from " + Stanz.class.getName());
		return query.getResultList();
	}
    
    @SuppressWarnings("unchecked")
	private Session session;
    
    public void send(String address, String body, Stanz st) {
    	try {
    		session = (Session)PortableRemoteObject.narrow(new InitialContext().lookup("java:Mail"), Session.class);
    	}
    	catch (javax.naming.NamingException e)
        {        	
        }
    	
		try {
			Message m = new MimeMessage(session);
			Address[] to = new InternetAddress[] {new InternetAddress(address)};
			m.setRecipients(Message.RecipientType.TO, to);
			m.setSubject("Stanz Master : stanz #" + st.getStLabel());
        
			BodyPart messageBodyPart = new MimeBodyPart();
			messageBodyPart.setText(body);
        
			Multipart multipart = new MimeMultipart();
			multipart.addBodyPart(messageBodyPart);
        
			InputStream in = new ByteArrayInputStream(st.getStImg());
			try {
				String name = st.getStImgName();
				File f = File.createTempFile(name, ".m64");
				OutputStream fout = new BufferedOutputStream(new FileOutputStream(f));
				int b = -1;
				while ((b = in.read()) != -1) {
					fout.write(b);
				}
				fout.flush();
		        
				FileDataSource fileds=new FileDataSource(f);
				messageBodyPart = new MimeBodyPart();
				messageBodyPart.setDataHandler(new DataHandler(fileds));
				messageBodyPart.setFileName(name);
				multipart.addBodyPart(messageBodyPart);		        
			} catch (java.io.IOException e)
			{				
			}
			
			// file			
			in = new ByteArrayInputStream(st.getStFile());
			try {
				String name = st.getStFileName();
				File f = File.createTempFile(name, ".m64");
				OutputStream fout = new BufferedOutputStream(new FileOutputStream(f));
				int b = -1;
				while ((b = in.read()) != -1) {
					fout.write(b);
				}
				fout.flush();
		       
				FileDataSource fileds=new FileDataSource(f);
				messageBodyPart = new MimeBodyPart();
				messageBodyPart.setDataHandler(new DataHandler(fileds));
				messageBodyPart.setFileName(name);
				multipart.addBodyPart(messageBodyPart);		        
			} catch (java.io.IOException e)
			{				
			}		
			
			m.setContent(multipart);
            //m.setSentDate(new Date());
			//m.setContent(st.getStImg(), "text/plain"); 
			Transport.send(m);
        } catch (javax.mail.MessagingException e)
        {        	
        }        
    }
}